/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine - graphics\scene
// Copyright (c) 2015.  All Rights Reserved
//
// File:		AE3DObject.h
// Author:		Gianluca Belardelli
// Date:		08/04/2015
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AE3DOBJECT_H_
#define _AE3DOBJECT_H_

/// \brief
///   Common base class for 3D objects
/// 
/// The AE3DObject class serves as base class for 3D engine objects such as entities,
/// lightsources, particle groups and paths. It stores information about the position, orientation
/// and motion delta of the object and provides functions for attaching the object to other
/// AE3DObject instances.
/// 
/// Use AE3DObject as a lightweight base class for your custom objects in case VisBaseEntity_cl
/// is not appropriate. Using the AE3DObject class simplifies the vForge integration and
/// parenting support of your custom objects.
/// 
/// Please note that the engine is not responsible for processing motion delta of  AE3DObject
/// instances. In case of entities the vHavokPhysicsModule takes care of this as long as a
/// physics object is available for the instance. When using a different physics system or other
/// AE3DObject derived classes your game code has to take care of processing the motion delta.
class AE3DObject
{
// Members
public:
	/// \brief Enumerativo per i flags che indicano lo stato corrente e le 
	/// modifiche applicate all'oggetto.
	enum AE3DOBJECT_FLAGS
	{
		AE3DOBJECT_NONE = 0,                    ///< Nessun flag impostato
		AE3DOBJECT_POSCHANGED = 1,              ///< La posizione dell'oggetto &egrave; cambiata.
		AE3DOBJECT_ORICHANGED = 2,              ///< L'orientamento dell'oggetto &egrave; cambiato.
		AE3DOBJECT_SCALINGCHANGED = 16,         ///< La scala dell'oggetto &egrave; cambiata.
		
		/// Combinazione di bit utilizzata per segnalare un cambiamento di posizione, orientamento e scaling.
		AE3DOBJECT_ALLCHANGED = ( AE3DOBJECT_POSCHANGED | AE3DOBJECT_ORICHANGED | AE3DOBJECT_SCALINGCHANGED ),
		
		AE3DOBJECT_USEEULERANGLES = 32,         /// L'oggetto utilizza gli Euler Angles.
		AE3DOBJECT_REPOSITION = 128,            /// Riposizionamento in una zona.
		
		// Bit combination of the flags that should be cleared after each change event
		AE3DOBJECT_CLEARCHANGED = ( AE3DOBJECT_ALLCHANGED | AE3DOBJECT_REPOSITION )
	};

protected:
	AEVector4f m_vcWorldPosition;				/// Posizione World fX,fY,fZ.
	AEVector4f m_vcOrientation;					///< orientation (yaw/pitch/roll)
	AEVector4f m_vcMotionDeltaWorldSpaceXYZ;	///< fX,fY,fZ motion delta in world space
	AEVector4f m_vcMotionDeltaLocalSpaceXYZ;	///< fX,fY,fZ motion delta in local space
	AEVector4f m_vcRotationDeltaXYZ;			///< fX,fY,fZ rotation delta
	AEVector4f m_vcLocalPosition;				///< local space position

	AEINT32 m_nFlags;                               ///< status flags
	AEINT32 m_nModifiedCtr;                         ///< Counter that gets increased whenever the position or orientation is modified (not serialized)
	AEBOOL32 m_bUpdateBindingInProgress;            ///< if TRUE then the world space position is currently being recomputed  

	mutable AEINT32 m_nInternalFlags;               ///< internal flags
	mutable AEMatrix4f m_matCachedRotMatrix;          ///< cached rotation matMatrix, gets recomputed when orientation changes
	
	// local space data
	AE3DObject *m_lpParent;                  ///< parent object
	AEMatrix4f m_matLocalOrientation;                 ///< local space orientation
	AEINT16 m_nSceneElementType;                  ///< set in the constructor of every class type. VIS_SCENEELEMENTTYPE_XYZ
	
	//VisObject3DVisData_cl *m_pVisData;          ///< visibility-related component; only needs to be present for objects using visibility handling (e.g. entities, lights, visibility objects)

// Methods
public:
	/** @name Construttori / Distruttore */
	/// @{
	/// \brief Costruttore di default.
	AE_DLLIMPEXP AE3DObject( void );
	
	/// \brief Distruttore di default.
	AE_DLLIMPEXP virtual ~AE3DObject( void );
	
	/// @}
	/** @name Posizione */
	/// @{
	
	/// \brief Imposta la posizione dell'oggetto nel World Space.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto.
	/// \param vcPos Vettore contenente la nuova posizione dell'oggetto.
	/// \sa AE3DObject::IncPosition
	/// \sa AE3DObject::GetPosition
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP void SetPosition( const AEVector4f &vcPos );
	
	/// \brief Incrementa la posizione dell'oggetto nel World Space.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto.
	/// \param vcPos Vettore contenente il delta di spostamento dell'oggetto in coordinate World Space.
	/// \sa AE3DObject::SetPosition
	/// \sa AE3DObject::GetPosition
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP void IncPosition( const AEVector4f &vcPos );
	
	/// \brief Ritorna la posizione dell'oggetto in coordinate World Space.
	/// \param vcPos Referenza ad un vettore contenente le coordinate dell'oggetto.
	/// \sa AE3DObject::SetPosition
	/// \sa AE3DObject::IncPosition
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP void GetPosition( AEVector4f &vcPos ) const;
	
	/// \brief Ritorna la posizione dell'oggetto in coordinate World Space.
	/// \return Referenza ad un vettore contenente le coordinate dell'oggetto.
	/// \sa AE3DObject::SetPosition
	/// \sa AE3DObject::IncPosition
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP const AEVector4f &GetPosition( void ) const;
	
	/// \brief Imposta la posizione dell'oggetto nel World Space utilizzando tre valori AEFLOAT32.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto.
	/// \param fX Nuova posizione X.
	/// \param fY Nuova posizione Y.
	/// \param fZ Nuova posizione Z.
	/// \sa AE3DObject::IncPosition
	/// \sa AE3DObject::GetPosition
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_FORCEINLINE void SetPosition( AEFLOAT32 fX, AEFLOAT32 fY, AEFLOAT32 fZ );
	
	/// \brief Incrementa la posizione dell'oggetto nel World Space utilizzando tre valori AEFLOAT32.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto.
	/// \param fX Nuova posizione X.
	/// \param fY Nuova posizione Y.
	/// \param fZ Nuova posizione Z.
	/// \sa AE3DObject::SetPosition
	/// \sa AE3DObject::GetPosition
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_FORCEINLINE void IncPosition( AEFLOAT32 fX, AEFLOAT32 fY, AEFLOAT32 fZ );
	
	/// \brief Ritorna la posizione dell'oggetto in coordinate World Space 
	/// utilizzando referenze a tre valori AEFLOAT32.
	/// \param fX Posizione corrente X.
	/// \param fY Posizione corrente Y.
	/// \param fZ Posizione corrente Z.
	/// \sa AE3DObject::SetPosition
	/// \sa AE3DObject::IncPosition
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP void GetPosition( AEFLOAT32 &fX, AEFLOAT32 &fY, AEFLOAT32 &fZ ) const;  
	
	/// \brief Metodo utilizzato per trasformare la posizione nelle coordinate
	/// Local Space dell'oggetto.
	/// Il metodo utilizza la posizione dell'oggetto e la matrice di rotazione per
	/// calcolare la trasformazione.
	/// \param vcWorldPos Posizione da trasformare
	/// \return Un vettore contenente la posizione nelle coordinate Local Space.
	/// \sa AE3DObject::GetPosition
	/// \sa AE3DObject::GetRotationMatrix
	AE_FORCEINLINE AEVector4f TransformToObjectSpace( const AEVector4f& vcWorldPos ) const;

	/// @}
	/** @name Orientamento (Yaw, Pitch, Roll) */
	/// @{
	/// \brief Imposta l'orientamento dell'oggetto nelle coordinate World Space,
	/// utilizzando gli angoli Euleriani.
	/// Se l'oggetto non &egrave; nella modalit&agrave; Euler Angle (SetUseEulerAngles), il metodo
	/// non cambier&agrave; l'attuale orientamento fino a che la modalit&agrave; Euler Angle sia
	/// di nuovo abilitata.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto. E' sconsigliato utilizzare questo metodo se l'oggetto &egrave;
	/// attaccato ad un altro a causa dei risultati ambigui restituiti dalla natura stessa
	/// degli angoli Euleriani. Utilizzare invece il metodo IncLocalOrientation.
	/// \param vcYPR Vettore contenente il nuovo orientamento dell'oggetto espresso con valori di
	/// Yaw, Pitch e Roll.
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP void SetOrientation( const AEVector4f &vcYPR );
	
	/// \brief Incrementa l'orientamento dell'oggetto nelle coordinate World Space,
	/// utilizzando gli angoli Euleriani.
	/// Se l'oggetto non &egrave; nella modalit&agrave; Euler Angle (SetUseEulerAngles), il metodo
	/// non cambier&agrave; l'attuale orientamento fino a che la modalit&agrave; Euler Angle sia
	/// di nuovo abilitata.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto. E' sconsigliato utilizzare questo metodo se l'oggetto &egrave;
	/// attaccato ad un altro a causa dei risultati ambigui restituiti dalla natura stessa
	/// degli angoli Euleriani. Utilizzare invece il metodo IncLocalOrientation.
	/// \param vcYPR Vettore contenente il delta dell'orientamento dell'oggetto espresso con valori di
	/// Yaw, Pitch e Roll.
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP void IncOrientation( const AEVector4f &vcYPR );
	
	/// \brief Ritorna l'orientamento dell'oggetto in coordinate World Space.
	/// Quando l'oggetto non &egrave; in modalit&agrave; Euler Angle (SetUseEulerAngles), il metodo
	/// non ritorner&agrave; l'orientamento attuale ma l'ultimo orientamento  di quando si trovava
	/// in modalit&agrave; Euler Angle. 
	/// \param vcYPR Referenza ad un vettore contenente i valori dell'orientamento dell'oggetto 
	/// espresso tramite Yaw, Pitch e Roll.
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP void GetOrientation( AEVector4f &vcYPR ) const;
		
	/// \brief Ritorna l'orientamento dell'oggetto in coordinate World Space.
	/// Quando l'oggetto non &egrave; in modalit&agrave; Euler Angle (SetUseEulerAngles), il metodo
	/// non ritorner&agrave; l'orientamento attuale ma l'ultimo orientamento  di quando si trovava
	/// in modalit&agrave; Euler Angle. 
	/// \returns Un vettore contenente i valori dell'orientamento dell'oggetto 
	/// espresso tramite Yaw, Pitch e Roll.
	/// \sa AE3DObject::GetActualOrientation
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP AEVector4f GetOrientation( void ) const;
	
	/// \brief Ritorna l'orientamento dell'oggetto in coordinate World Space.
	/// Il metodo ritorner&agrave; l'orientamento attuale indipendentemente dallo stato UseEulerAngles.
	/// \returns Un vettore contenente i valori dell'orientamento dell'oggetto 
	/// espresso tramite Yaw, Pitch e Roll.
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP AEVector4f GetActualOrientation( void ) const;
	
	/// \brief Imposta l'orientamento dell'oggetto nelle coordinate World Space,
	/// utilizzando gli angoli Euleriani espressi tramite tre valori AEFLOAT32.
	/// Se l'oggetto non &egrave; nella modalit&agrave; Euler Angle (SetUseEulerAngles), il metodo
	/// non cambier&agrave; l'attuale orientamento fino a che la modalit&agrave; Euler Angle sia
	/// di nuovo abilitata.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto. E' sconsigliato utilizzare questo metodo se l'oggetto &egrave;
	/// attaccato ad un altro a causa dei risultati ambigui restituiti dalla natura stessa
	/// degli angoli Euleriani. Utilizzare invece il metodo IncLocalOrientation.
	/// \param fY Valore dell'angolo Yaw.
	/// \param fP Valore dell'angolo Pitch.
	/// \param fR Valore dell'angolo Roll.	
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_FORCEINLINE void SetOrientation( AEFLOAT32 fY, AEFLOAT32 fP, AEFLOAT32 fR );
	
	/// \brief Incrementa l'orientamento dell'oggetto nelle coordinate World Space,
	/// utilizzando gli angoli Euleriani espressi tramite tre valori AEFLOAT32.
	/// Se l'oggetto non &egrave; nella modalit&agrave; Euler Angle (SetUseEulerAngles), il metodo
	/// non cambier&agrave; l'attuale orientamento fino a che la modalit&agrave; Euler Angle sia
	/// di nuovo abilitata.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto. E' sconsigliato utilizzare questo metodo se l'oggetto &egrave;
	/// attaccato ad un altro a causa dei risultati ambigui restituiti dalla natura stessa
	/// degli angoli Euleriani. Utilizzare invece il metodo IncLocalOrientation.
	/// \param fY Valore dell'angolo Yaw.
	/// \param fP Valore dell'angolo Pitch.
	/// \param fR Valore dell'angolo Roll.	
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_FORCEINLINE void IncOrientation( AEFLOAT32 fY, AEFLOAT32 fP, AEFLOAT32 fR );
	
	/// \brief Ritorna l'orientamento dell'oggetto in coordinate World Space.
	/// Quando l'oggetto non &egrave; in modalit&agrave; Euler Angle (SetUseEulerAngles), il metodo
	/// non ritorner&agrave; l'orientamento attuale ma l'ultimo orientamento  di quando si trovava
	/// in modalit&agrave; Euler Angle. 
	/// \param fY Valore corrente dell'angolo Yaw.
	/// \param fP Valore corrente dell'angolo Pitch.
	/// \param fR Valore corrente dell'angolo Roll.
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP void GetOrientation( AEFLOAT32 &fY, AEFLOAT32 &fP, AEFLOAT32 &fR ) const;

	/// @}
	/** @name Angoli Euleriani */
	/// @{
	/// \brief Abilita o disabilita la modalit&agrave; Euler Angle.
	/// Nella modalit&agrave; Euler Angle ( il default ) l'orientamento di un'entit&agrave; &egrave;
	/// specificato attraverso tre angoli Euleriani ( Yaw, Pitch e Roll ) utilizzando i metodi
	/// SetOrientation/IncOrientation. Utilizzando SetRotationMatrix in questa modalit&agrave;
	/// la matrice passata come parametro sar&agrave; convertita in angoli Euleriani.
	/// Nella modalit&agrave; Matrice invece la matrice passata come parametro sar&agrave;
	/// copiata direttamente. In questa modalit&agrave; tutte le operazioni che utilizzano
	/// angoli Euleriani saranno ignorate fino a che non sar&agrave; abilitata la modalit&agrave;
	/// Euler Angle.
	/// La modalit&agrave; Euler Angle &egrave; da preferire, ma per implementare esternamente
	/// operazioni di fisica la modalit&agrave; Matrice si presta meglio allo scopo.
	/// \param bStatus AETRUE se si vuole utilizzare la modalit&agrave; Euler Angle altrimenti
	/// AEFALSE. Lo stato di default &egrave; AETRUE.
	/// \sa AE3DObject::GetUseEulerAngles
	/// \sa AE3DObject::SetRotationMatrix
	AE_DLLIMPEXP void SetUseEulerAngles( AEBOOL32 bStatus );
	
	/// \brief Ritorna la modalit&agrave; impostata.
	/// \return AETRUE se la modalit&agrave; Euler Angle &egrave; impostata altrimenti AEFALSE
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetRotationMatrix
	AE_DLLIMPEXP AEBOOL32 GetUseEulerAngles( void ) const;

	/// @}
	/** @name Operazioni con matrici */
	/// @{
	/// \brief Imposta la matrice di rotazione dell'oggetto nelle coordinate World Space.
	/// Se l'oggetto si trova nella modalit&agrave; Euler Angle la matrice sar&agrave; convertita
	/// in angoli Euleriani, questa conversione viene effettuata per ogni cambiamento della matrice.
	/// Ricalcola la posizione nel Local Space dell'oggetto nel caso in cui sia attaccato
	/// ad un altro oggetto.
	/// \param matMatrix Referenza alla nuova matrice di rotazione dell'oggetto.
	/// \note Per passare una matrice di rotazione senza effettuare la conversione, l'oggetto
	/// dovrebbe trovarsi nella modalit&agrave; SetUseEulerAngles( AEFALSE ).
	/// \sa AE3DObject::GetRotationMatrix
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP void SetRotationMatrix( const AEMatrix4f &matMatrix );
	
	/// \brief Ritorna la matrice di rotazione nelle coordinate World Space.
	/// Quando l'oggetto si trova nella modalit&agrave; Euler Angle, la matrice verr&agrave; creata
	/// utilizzando gli angoli Euleriani. Se la modalit&agrave; &egrave; disabilitata la matrice
	/// sar&agrave; impostata con la matrice passata a SetRotationMatrix;
	/// \param matMatrix Referenza alla matrice di rotazione attuale.
	/// \sa AE3DObject::SetRotationMatrix
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation  
	AE_DLLIMPEXP void GetRotationMatrix( AEMatrix4f &matMatrix ) const;
	
	/// \brief Metodo che combina la chiamata ai due metodi SetPosition e SetRotationMatrix.
	/// Il metodo dovrebbe essere utilizzato solo se posizione e rotazione devono essere aggiornate.
	/// \param vcPos Vettore contenente la nuova posizione.
	/// \param matMatrix Matrice contenente la nuova rotazione.
	/// \sa AE3DObject::SetPosition
	/// \sa AE3DObject::SetRotationMatrix
	AE_DLLIMPEXP void SetPositionAndRotation( const AEVector4f &vcPos, const AEMatrix4f &matMatrix );
	
	/// \brief Metodo che combina la chiamata ai due metodi SetPosition e SetRotationMatrix.
	/// Il metodo dovrebbe essere utilizzato solo se posizione e rotazione devono essere aggiornate.
	/// \param vcPos Vettore contenente la nuova posizione.
	/// \param vcYPR Vettore contenente il nuovo orientamento.
	/// \sa AE3DObject::SetPositionAndRotation
	AE_DLLIMPEXP void SetPositionAndOrientation( const AEVector4f &vcPos, const AEVector4f &vcYPR );
	
	/// \brief Metodo interno per assicurare che il membro protetto m_matCachedRotMatrix sia sempre aggiornato.
	AE_DLLIMPEXP void EnsureCachedRotationMatrixValid( void ) const;
	
	/// \brief Ritorna la matrice di rotazione nelle coordinate World Space.
	/// Quando l'oggetto si trova nella modalit&agrave; Euler Angle, la matrice verr&agrave; creata
	/// utilizzando gli angoli Euleriani. Se la modalit&agrave; &egrave; disabilitata la matrice
	/// sar&agrave; impostata con la matrice passata a SetRotationMatrix;
	/// \return Referenza alla matrice di rotazione attuale.
	/// \sa AE3DObject::SetRotationMatrix
	/// \sa AE3DObject::SetOrientation
	/// \sa AE3DObject::IncOrientation
	/// \sa AE3DObject::GetOrientation
	/// \sa AE3DObject::SetUseEulerAngles
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation  
	AE_DLLIMPEXP const AEMatrix4f &GetRotationMatrix( void ) const;
	
	/// \brief Ritorna la matrice di rotazione trasposta.
	/// \return La versione trasposta della corrente matrice di rotazione.
	AE_DLLIMPEXP AEMatrix4f GetTransposedRotationMatrix( void ) const;
	
	/// \brief Ritorna la direzione dell'asse X.
	/// La direzione corrisponde all'asse X della matrice (m[0], m[3], m[6]).
	/// \return Un vettore contenente l'orientamento della matrice.
	AE_DLLIMPEXP AEVector4f GetDirection( void ) const;
	
	/// \brief Imposta la direzione di vista dell'oggetto.
	/// Il metodo compone la matrice dal vettore contenente la direzione passato come argomento e
	/// la imposta utilizzando AE3DObject::SetRotationMatrix. Utilizza la funzione Math.MatrixLookAt
	/// con (0, 0, 1) come upVector.
	/// \param vcDir Direzione di vista dell'oggetto.
	AE_DLLIMPEXP void SetDirection( const AEVector4f &vcDir );
	
	/// @}
	/** @name Sistema di Parent/Child */
	/// @{
	/// \brief Attacca questo oggetto all'oggetto padre specificato.
	/// L'oggetto attaccato mantiene la posizione e l'orientamento corrente. 
	/// Se l'oggetto risulta attaccato ad un altro oggetto questo metodo esegue prima un detach dal
	/// vecchio oggetto.
	/// Gli oggetti figli mantengono le loro trasformazioni internamente nello spazio locale e
	/// aggiornano lo spazio World quando una trasformazione locale o una trasformazione del
	/// padre cambiano.
	/// \param lpParent Oggetto padre.
	/// \sa AE3DObject::DetachFromParent
	/// \sa AE3DObject::GetParent
	/// \sa AE3DObject::ResetLocalTransformation
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP void AttachToParent( AE3DObject *lpParent );
	
	/// \brief Stacca l'oggetto dal suo parent.
	/// La chiamata al metodo sar&agrave; ignorata qualora l'oggetto non ha padre.
	/// \sa AE3DObject::AttachToParent
	/// \sa AE3DObject::GetParent
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP void DetachFromParent( void );
	
	/// \brief Ritorna l'oggetto padre di questo.
	/// \return AENULL se l'oggetto non ha padre.
	/// \sa AE3DObject::AttachToParent
	/// \sa AE3DObject::DetachFromParent
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	/// \sa VisModuleSystemParent_c::GetChild
	AE_DLLIMPEXP AE3DObject *GetParent( void ) const;
	
	/// \brief Imposta la posizione dell'oggetto nelle coordinate Local Space.
	/// Ricalcola la posizione e l'orientamento World dell'oggetto.
	/// Il metodo non ha alcun effetto se l'oggetto non ha un padre.
	/// \param vcPos Vettore contenente la nuova posizione locale.
	/// \sa AE3DObject::GetLocalPosition
	AE_DLLIMPEXP void SetLocalPosition( const AEVector4f &vcPos );
	
	/// \brief Imposta la posizione dell'oggetto nelle coordinate Local Space
	/// utilizzando tre valori AEFLOAT32.
	/// Ricalcola la posizione e l'orientamento World dell'oggetto.
	/// Il metodo non ha alcun effetto se l'oggetto non ha un padre.
	/// \param fX Nuova posizione locale X.
	/// \param fY Nuova posizione locale Y.
	/// \param fZ Nuova posizione locale Z.
	/// \sa AE3DObject::GetLocalPosition
	AE_FORCEINLINE void SetLocalPosition( AEFLOAT32 fX, AEFLOAT32 fY, AEFLOAT32 fZ );
	
	/// \brief Ritorna la posizione locale dell'oggetto.
	/// La posizione &egrave; valida solo se l'oggetto ha un padre.
	/// \return Referenza ad un vettore contenente la posizione locale.
	/// \sa AE3DObject::SetLocalPosition
	AE_DLLIMPEXP const AEVector4f &GetLocalPosition( void ) const;
	
	/// \brief Imposta l'orientamento locale dell'oggetto tramite valori di Yaw, Pitch e Roll.
	/// Ricalcola la posizione e l'orientamento World dell'oggetto.
	/// Il metodo non ha alcun effetto se l'oggetto non ha un padre.
	/// \param vcYPR Vettore contenente il nuovo orientamento locale.
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP void SetLocalOrientation( const AEVector4f &vcYPR );  
	
	/// \brief Imposta l'orientamento locale dell'oggetto tramite valori di Yaw, Pitch e Roll
	/// espressi con tre AEFLOAT32.
	/// Ricalcola la posizione e l'orientamento World dell'oggetto.
	/// Il metodo non ha alcun effetto se l'oggetto non ha un padre.
	/// \param fY Nuovo orientamento locale di Yaw.
	/// \param fP Nuovo orientamento locale di Pitch.
	/// \param fR Nuovo orientamento locale di Roll.
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	/// \sa AE3DObject::GetLocalOrientation
	AE_DLLIMPEXP void SetLocalOrientation( const AEFLOAT32 fY,const AEFLOAT32 fP,const AEFLOAT32 fR );
	
	/// \brief Ritorna l'orientamento locale dell'oggetto tramite valori di Yaw, Pitch e Roll.
	/// L'orientamento &egrave; valido solo se l'oggetto ha un padre.
	/// \return Vettore contenente i valori di orientamento locale.
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	/// \sa AE3DObject::SetLocalOrientation
	AE_DLLIMPEXP AEVector4f GetLocalOrientation( void ) const;
	
	/// \brief Imposta la matrice di orientamento locale dell'oggetto.
	/// Ricalcola la posizione e l'orientamento World dell'oggetto.
	/// Il metodo non ha alcun effetto se l'oggetto non ha un padre.
	/// \param matMatrix Nuova matrice di orientamento locale.
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientationMatrix
	AE_DLLIMPEXP void SetLocalOrientationMatrix( const AEMatrix4f &matMatrix );  
	
	/// \brief Metodo che combina in un'unica chiamata i metodi 
	/// SetLocalPosition e SetLocalOrientationMatrix.
	/// \param vcPos Vettore contenente la nuova posizione locale.
	/// \param matMatrix Matrice contenente il nuovo orientamento locale.
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::SetLocalOrientationMatrix
	AE_DLLIMPEXP void SetLocalTransform( const AEVector4f &vcPos, const AEMatrix4f &matMatrix );
	
	/// \brief Ritorna la matrice di orientamento locale dell'oggetto.
	/// L'orientamento &egrave; valido solo se l'oggetto ha un padre.
	/// \return Referenza ad una matrice contenente il corrente orientamento locale dell'oggetto.
	/// \sa AE3DObject::SetLocalPosition
	/// \sa AE3DObject::GetLocalPosition
	/// \sa AE3DObject::SetLocalOrientation
	/// \sa AE3DObject::GetLocalOrientation
	/// \sa AE3DObject::SetLocalOrientationMatrix
	AE_DLLIMPEXP const AEMatrix4f &GetLocalOrientationMatrix( void ) const;
	
	/// \brief Reimposta la posizione e l'orientamento locale a (0/0/0).
	/// \sa AE3DObject::SetLocalPosition
	AE_DLLIMPEXP void ResetLocalTransformation( void );
	
	/// @}
	/** @name Delta di movimento */
	/// @{
	
	/// \brief Imposta il valore Delta di movimento, in coordinate World, dell'oggetto.
	/// Il valore Delta descrive la differenza tra la posizione corrente e la posizione
	/// che l'oggetto dovrebbe raggiungere dopo che il sistema di animazione ha applicato il movimento.
	/// Due valori Delta sono memorizzati per ogni oggetto, uno &egrave; espresso in coordinate
	/// World l'altro in coordinate Local relativo all'orientamento dell'oggetto.
	/// Il sistema fisico eseguir&agrave; il seguente pseudo-codice:
	///  \code
	///    pObject->IncOrientation(pObject->GetRotationDelta());
	///    pObject->ResetRotationDelta();
	///    
	///    AEVector4f vcMotionDelta = pObject->GetMotionDeltaWorldSpace() + pObject->GetRotationMatrix() * pObject->GetMotionDeltaLocalSpace();
	///    pObject->ResetMotionDelta();
	///  \endcode
	///  muovendo fisicamente l'oggetto di un valore risultante da vcMotionDelta.
	/// \param vcMotionDelta Vettore contenente il Delta di movimento.
	/// \sa AE3DObject::IncMotionDeltaWorldSpace
	/// \sa AE3DObject::GetMotionDeltaWorldSpace
	/// \sa AE3DObject::ResetMotionDeltaWorldSpace
	AE_DLLIMPEXP void SetMotionDeltaWorldSpace( const AEVector4f &vcMotionDelta );
	
	/// \brief Imposta il valore Delta di movimento, in coordinate Local, dell'oggetto.
	/// Il valore Delta descrive la differenza tra la posizione corrente e la posizione
	/// che l'oggetto dovrebbe raggiungere dopo che il sistema di animazione ha applicato il movimento.
	/// Due valori Delta sono memorizzati per ogni oggetto, uno &egrave; espresso in coordinate
	/// World l'altro in coordinate Local relativo all'orientamento dell'oggetto.
	/// Il sistema fisico eseguir&agrave; il seguente pseudo-codice:
	///  \code
	///    pObject->IncOrientation(pObject->GetRotationDelta());
	///    pObject->ResetRotationDelta();
	///    
	///    AEVector4f vcMotionDelta = pObject->GetMotionDeltaWorldSpace() + pObject->GetRotationMatrix() * pObject->GetMotionDeltaLocalSpace();
	///    pObject->ResetMotionDelta();
	///  \endcode
	///  muovendo fisicamente l'oggetto di un valore risultante da vcMotionDelta.
	/// \param vcMotionDelta Vettore contenente il Delta di movimento.
	/// \note Il Delta di movimento Locale &grave; modificato dal sistema di animazione, quindi 
	/// bisognerebbe tenerne conto se deve essere utilizzato nel codice utente altrimenti il valore
	/// viene resettato o sovrascritto. Togliendo il flag APPLY_MOTION_DELTA dalla configurazione del
	/// sistema di animazione &egrave; possibile utilizzare il valore di Delta Locale con sicurezza
	/// all'interno del codice utente.
	/// \sa AE3DObject::IncMotionDeltaLocalSpace
	/// \sa AE3DObject::GetMotionDeltaLocalSpace
	/// \sa AE3DObject::ResetMotionDeltaLocalSpace
	AE_DLLIMPEXP void SetMotionDeltaLocalSpace( const AEVector4f &vcMotionDelta ); 
	
	/// \brief Incrementa il Delta di spostamento dell'oggetto nelle coordinate World.
	/// Consultare la documentazione di SetMotionDeltaWorldSpace per maggiori informazioni.
	/// \param vcMotionDelta Vettore contenente il Delta da aggiungere al vettore di posizione World.
	/// \sa AE3DObject::SetMotionDeltaWorldSpace
	AE_DLLIMPEXP void IncMotionDeltaWorldSpace( const AEVector4f &vcMotionDelta );
	
	/// \brief Incrementa il Delta di spostamento dell'oggetto nelle coordinate Local.
	/// Consultare la documentazione di SetMotionDeltaLocalSpace per maggiori informazioni.
	/// \param vcMotionDelta Vettore contenente il Delta da aggiungere al vettore di posizione Local.
	/// \sa AE3DObject::SetMotionDeltaLocalSpace
	AE_DLLIMPEXP void IncMotionDeltaLocalSpace( const AEVector4f &vcMotionDelta ); 
	
	/// \brief Ritorna il Delta di spostamento dell'oggetto in coordinate World.
	/// Consultare la documentazione di SetMotionDeltaWorldSpace per maggiori informazioni.
	/// \sa AE3DObject::SetMotionDeltaWorldSpace
	AE_DLLIMPEXP const AEVector4f &GetMotionDeltaWorldSpace( void ) const;
	
	/// \brief Ritorna il Delta di spostamento dell'oggetto in coordinate Space.
	/// Consultare la documentazione di SetMotionDeltaLocalSpace per maggiori informazioni.
	/// \sa AE3DObject::SetMotionDeltaLocalSpace
	AE_DLLIMPEXP const AEVector4f &GetMotionDeltaLocalSpace( void ) const;
	
	/// \brief Azzera il Delta di movimento dell'oggetto nelle coordinate World.
	/// Il metodo si occupa di impostare a 0 il Delta di movimento dell'oggetto nelle coordinate World.
	/// Il metodo virtuale ResetMotionDelta esegue anche altri task come ad esempio
	/// resettare il Delta accumulato.
	/// Vedere la documentazione di SetMotionDeltaWorldSpace per maggiori informazioni.
	/// \sa AE3DObject::SetMotionDeltaWorldSpace
	/// \sa AE3DObject::ResetMotionDelta
	AE_DLLIMPEXP void ResetMotionDeltaWorldSpace( void );
	
	/// \brief Azzera il Delta di movimento dell'oggetto nelle coordinate Local.
	/// Il metodo si occupa di impostare a 0 il Delta di movimento dell'oggetto nelle coordinate Local.
	/// Il metodo virtuale ResetMotionDelta esegue anche altri task come ad esempio
	/// resettare il Delta accumulato.
	/// Vedere la documentazione di SetMotionDeltaLocalSpace per maggiori informazioni.
	/// \sa AE3DObject::SetMotionDeltaLocalSpace
	/// \sa AE3DObject::ResetMotionDelta
	AE_DLLIMPEXP void ResetMotionDeltaLocalSpace( void );
	
	/// \brief Azzera il Delta di movimento dell'oggetto sia nelle coordinate Local
	/// che nelle World.
	/// Il metodo &egrave; virtuale e le classi derivate devono fornire una loro implementazione.
	/// \sa AEBaseEntity::ResetMotionDelta
	AE_DLLIMPEXP virtual void ResetMotionDelta( void );
	
	/// @}
	/** @name Delta di rotazione */
	/// @{
	/// \brief Imposta il Delta di rotazione dell'oggetto.
	/// Le componenti del vettore specificano rispettivamente Yaw, Pitch e Roll
	/// espresse in gradi.
	/// \param vcRotationDelta Vettore contenente il Delta di rotazione.
	/// \note Il sistema di animazione si occupa di applicare il Delta di rotazione agli oggetti animati.
	/// E' possibile rimuovere il flag APPLY_MOTION_DELTA dalla configurazione del sistema di animazione
	/// per disabilitare il Delta di rotazione durante le animazioni.
	/// \sa AE3DObject::GetRotationDelta
	/// \sa AE3DObject::IncRotationDelta
	/// \sa AE3DObject::ResetRotationDelta
	/// \sa AE3DObject::HasRotationDelta
	/// \sa AE3DObject::SetMotionDelta
	AE_DLLIMPEXP void SetRotationDelta( const AEVector4f &vcRotationDelta );
	
	/// \brief Incrementa il Delta di rotazione dell'oggetto, nel frame corrente.
	/// Le componenti del vettore specificano rispettivamente Yaw, Pitch e Roll
	/// espresse in gradi.
	/// \param vcRotationDelta Vettore contenente il Delta di rotazione.
	/// \note Il sistema di animazione si occupa di applicare il Delta di rotazione agli oggetti animati.
	/// E' possibile rimuovere il flag APPLY_MOTION_DELTA dalla configurazione del sistema di animazione
	/// per disabilitare il Delta di rotazione durante le animazioni.
	/// \sa AE3DObject::SetRotationDelta
	/// \sa AE3DObject::GetRotationDelta
	/// \sa AE3DObject::ResetRotationDelta
	/// \sa AE3DObject::HasRotationDelta
	/// \sa AE3DObject::SetMotionDelta
	AE_DLLIMPEXP void IncRotationDelta( const AEVector4f &vcRotationDelta );
	
	/// \brief
	///   Resets the rotation delta of the object
	/// 
	/// in the current frame. 
	/// 
	/// \sa AE3DObject::SetRotationDelta
	/// \sa AE3DObject::GetRotationDelta
	/// \sa AE3DObject::IncRotationDelta
	/// \sa AE3DObject::HasRotationDelta
	/// \sa AE3DObject::SetMotionDelta
	AE_DLLIMPEXP void ResetRotationDelta( void );
	
	/// \brief
	///   Returns the rotation delta of the object
	/// 
	/// in the current frame. The components of the vector specify the yaw, pitch and roll angle (in
	/// degrees) respectively.
	/// 
	/// The return vector receives the angles to be added to the current frame, so the values are
	/// framerate dependent
	/// 
	/// \return
	///   AEVector4f& vcRotationDelta: current rotation delta
	/// 
	/// \note Il sistema di animazione si occupa di applicare il Delta di rotazione agli oggetti animati.
	/// E' possibile rimuovere il flag APPLY_MOTION_DELTA dalla configurazione del sistema di animazione
	/// per disabilitare il Delta di rotazione durante le animazioni.
	/// \sa AE3DObject::SetRotationDelta
	/// \sa AE3DObject::IncRotationDelta
	/// \sa AE3DObject::ResetRotationDelta
	/// \sa AE3DObject::HasRotationDelta
	/// \sa AE3DObject::SetMotionDelta
	AE_DLLIMPEXP const AEVector4f &GetRotationDelta( void ) const;
	
	/// \brief
	///   Indicates, whether the object has got rotation delta in the current frame
	/// 
	/// It is the same result as testing the rotation vector obtained with GetRotationDelta() to  be
	/// the zero vector
	/// 
	/// \return
	///   AEBOOL32 status: TRUE, if the current rotation delta vector is other than (0,0,0)
	/// 
	/// \note Il sistema di animazione si occupa di applicare il Delta di rotazione agli oggetti animati.
	/// E' possibile rimuovere il flag APPLY_MOTION_DELTA dalla configurazione del sistema di animazione
	/// per disabilitare il Delta di rotazione durante le animazioni.
	/// \note
	///   There is also a function VisAnimSequence_cl::HasRotationDelta, which returns TRUE, if the
	///   sequence has got rotation delta at all. In contrast, this function returns TRUE if the
	///   rotation of the current frame is other than (0,0,0)
	/// 
	/// \sa AE3DObject::SetRotationDelta
	/// \sa AE3DObject::IncRotationDelta
	/// \sa AE3DObject::ResetRotationDelta
	/// \sa AE3DObject::GetRotationDelta
	/// \sa VisAnimSequence_cl::HasRotationDelta
	AE_DLLIMPEXP AEBOOL32 HasRotationDelta( void ) const;
	
	///
	/// @}
	///
	
	///
	/// @name Misc
	/// @{
	///
	
	
	/// \brief
	///   Gets the flags of the 3D object.
	/// 
	///  These flags indicate whether certain object properties (such as position, orientation) have
	/// been modified since the last frame.
	/// 
	/// The return value of this function is only valid within the OnObject3DChanged virtual function
	/// call. Use it there to determine which components of the object have been modified.
	/// 
	/// \return
	///   AEINT32 nFlags: currently set flags, see AE3DOBJECT_FLAGS
	/// 
	/// \sa AE3DObject::SetO3DFlags
	AE_FORCEINLINE AEINT32 GetO3DFlags( void ) const;
	
	
	/// \brief
	///   Sets the flags of the 3D object.
	/// 
	/// Sets the flags of the 3D object indicating whether certain properties have been modified
	/// since the last frame. This function is supposed to be for internal use only. Modifications to
	/// the flags can lead to unpredictable results.
	/// 
	/// \param nFlags
	///   new flags, see AE3DOBJECT_FLAGS
	/// 
	/// \sa AE3DObject::SetO3DFlags
	AE_FORCEINLINE void SetO3DFlags( AEINT32 nFlags );
	
	
	/// \brief
	///   Gets the counter that gets increased whenever the position or orientation is modified.
	/// 
	/// You can use this counter to detect whether the transformation of the object has been
	/// changed during a specific time span.
	/// 
	/// \return
	///   AEINT32 iCtr: integer counter
	AE_FORCEINLINE AEINT32 GetModifiedCtr( void );
	
	
	
	///
	/// @}
	///
	
	///
	/// @name Object Directions
	/// @{
	///
	
	
	/// \brief
	///   Gets the direction the object is facing to (fX-axis)
	/// 
	/// The direction corresponds to the front vector (fX-axis) of the matMatrix (m[0], m[3], m[6])
	/// 
	/// \return
	///   AEVector4f frontDir
	AE_FORCEINLINE AEVector4f GetObjDir( void ) const;
	
	/// \brief
	///   Gets the direction facing to the right from the object (fY-axis)
	/// 
	/// The direction corresponds to the right vector (fY-axis) of the matMatrix (m[1], m[4], m[7])
	/// 
	/// \return
	///   AEVector4f& rightDir
	AE_FORCEINLINE AEVector4f GetObjDir_Right( void ) const;
	
	
	/// \brief
	///   Gets the direction facing upwards from the object (fZ-axis)
	/// 
	/// The direction corresponds to the up vector (fZ-axis) of the matMatrix (m[2], m[5], m[8])
	/// 
	/// \return
	///   AEVector4f& upDir
	AE_FORCEINLINE AEVector4f GetObjDir_Up( void ) const;
	
	/// \brief
	///   Returns the VisObject3DVisData_cl object associated with this AE3DObject.
	/// 
	/// A VisObject3DVisData_cl has to be defined in AE3DObject instances that are to be used in
	/// visibility determination, since the VisObject3DVisData_cl class takes care of visibility zone
	/// assignment and transitioning between visibility zones.
	/// 
	/// Dynamic scene elements in the Vision engine for which visibility determination is used
	/// automatically generate their own VisObject3DVisData_cl objects (e.g. entities, context
	/// cameras, light sources, and visibility objects). Custom AE3DObject types have to  create
	/// their own VisObject3DVisData_cl if visibility zone assignments should be tracked for them.
	/// 
	/// \return
	///   VisObject3DVisData_cl *: The visibility data object, or NULL if no VisObject3DVisData_cl is
	///   set.
	//AE_FORCEINLINE VisObject3DVisData_cl *GetVisData() { return m_pVisData; }
	
	
	/// \brief
	///   Returns the Scene Element Type of this AE3DObject.
	/// 
	/// Scene element types are used to identify different types of scene elements, e.g. during
	/// visibility zone assignment.
	/// 
	/// For a list of scene element types, refer to the VisSceneElementType_e enumeration.
	/// 
	/// Vision's built-in scene element types automatically set this member. Custom types will have
	/// to set the m_nSceneElementType member to VIS_SCENEELEMENTTYPE_CUSTOM.
	/// 
	/// \return
	///   AEUINT32: One of the values in the VisSceneElementType_e enumeration.
	AE_FORCEINLINE AEUINT32 GetSceneElementType( void ) const;
	
	
	
	/// \brief
	///   Recomputes the visibility.
	/// 
	/// ReComputeVisibility sets a flag which causes the engine to recompute the visibility zone
	/// assignments for this object. You have to call this function whenever the object teleports to
	/// another location outside of the nodes it is currently assigned to, or when it crosses
	/// visibility zone boundaries in an "illegal" way.
	/// 
	/// All children of this entity will automatically recompute the visibility zone assignments as
	/// well. 
	AE_DLLIMPEXP void ReComputeVisibility( void );
	
	
	///
	/// @}
	///
	
	///
	/// @name Misc Overrides
	/// @{
	///
	
	AE_DLLIMPEXP void Release( void );
	
	///
	/// @}
	///
	
	///
	/// @}
	///
	
	protected:
	friend void SetObject3DMatrix( AE3DObject *lpObject );
	
	/// \brief
	///   Override this function to keep track of position or orientation modifications.
	/// 
	/// This virtual function gets called whenever the position, orientation or motion/rotation delta
	/// of the object has been modified. Override this function to listen to position and orientation
	/// changes.  The passed flags indicate which components of the object have been modified, see
	/// AE3DOBJECT_FLAGS enumeration for more details. 
	/// 
	/// Don't forget to call the base implementation when overriding this function. The base
	/// implementation takes care  of calling the
	/// VisModuleSystemParent_cl::ModSysNotifyFunctionParentAltered function when necessary.
	/// 
	/// Note that the object modifications don't get grouped, OnObject3DChanged might thus get called
	/// multiple times per frame.
	/// 
	/// \param iO3DFlags
	///   AE3DOBJECT_FLAGS flags indicating the modified components
	//AE_DLLIMPEXP virtual void OnObject3DChanged( AEINT32 nO3DFlags );
	
	/// \brief
	///   Recomputes the local space position and triggers the virtual OnObject3DChanged function.
	/// 
	/// This function recomputes the local space transformation and triggers the virtual
	/// OnObject3DChanged function (which e.g. informs the attached children about state changes).
	/// 
	/// However, the operation is skipped if the world space transformation is currently  being
	/// recomputed (=UpdateBinding is called). In that case UpdateBinding takes  care of updating
	/// necessary dependencies when all recomputations have been done.
	AE_FORCEINLINE void UpdateDependencies( void )
	{
	// When modifying this function also make sure that you reflect the changes in the
	// UpdateBinding implementation.
	if (m_bUpdateBindingInProgress)
	return;
	
	if ( m_lpParent )
	ComputeLocalSpaceData();
	//OnObject3DChanged(m_nFlags);
	}
	
	/// \brief
	///   Clears the modification related flags (AE3DOBJECT_ALLCHANGED) from the Object3D flags.
	AE_DLLIMPEXP void ClearO3DChangeFlags( void );
	
	/// \brief
	///   Ensures that the orientation of the object is within the valid range of -180 and 180.
	AE_DLLIMPEXP void MakeValidOrientation( void );
	
	/// \brief
	///   Recomputes the world space transformation from the current local space transformation
	AE_DLLIMPEXP void UpdateBinding( void );
	
	/// \brief
	///   Recomputes the local space transformation from the current world space transformation
	AE_DLLIMPEXP void ComputeLocalSpaceData( void );
	
	
	///
	/// @}
	///
	
};


/*
/// \brief
///   Class containing data used as a template when constructing a new Object3D instance
/// 
/// It is currently only used as the base class for VisEntityTemplate_cl
class VisObject3DTemplate_cl
{
public:

  /// \brief
  ///   Constructor for an object creation template
  VisObject3DTemplate_cl(const char *pszClassName = NULL)
  {
    m_pClassType = NULL;
    m_pszClassName = pszClassName;
    m_pszObjectKey = NULL;
    m_vcWorldPosition.setZero();
    m_vScale.set(1.f, 1.f, 1.f);
    m_vRotation.setZero();
  }
  
  /// \brief
  ///   The class name of the new object, e.g. "VisBaseEntity_cl". Mutually exclusive with m_pClassType.
  const char *m_pszClassName;
    
  /// \brief
  ///   The class type of the new object, e.g. VisBaseEntity_cl::GetClassTypeId(). Mutually exclusive with m_pszClassName.
  VType* m_pClassType;
    
  /// \brief
  ///   The position of the new entity
  AEVector4f m_vcWorldPosition;
  
  /// \brief
  ///   The rotation of the new entity
  AEVector4f m_vRotation;
  
  /// \brief
  ///   The scale of the new entity
  AEVector4f m_vScale;

  /// \brief
  ///   Optional string that initializes the object key (SetObjectKey).
  const char *m_pszObjectKey;

};
*/

#include "AE3DObject.inl"

#endif  // _AE3DOBJECT_H_
